package cn.gemiman.daoyi.module.cms.service.articledetail;

import cn.gemiman.daoyi.framework.common.pojo.PageResult;
import cn.gemiman.daoyi.framework.common.util.object.BeanUtils;
import cn.gemiman.daoyi.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.gemiman.daoyi.module.cms.controller.admin.articledetail.vo.ArticleDetailPageReqVO;
import cn.gemiman.daoyi.module.cms.controller.admin.articledetail.vo.ArticleDetailSaveReqVO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.articledetail.ArticleDetailDO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.tagdictionary.TagDictionaryDO;
import cn.gemiman.daoyi.module.cms.dal.mysql.articledetail.ArticleDetailMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.tagdictionary.TagDictionaryMapper;
import cn.hutool.core.collection.CollUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import static cn.gemiman.daoyi.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.gemiman.daoyi.module.cms.enums.ErrorCodeConstants.ARTICLE_DETAIL_NOT_EXISTS;

/**
 * 文章 Service 实现类
 *
 * @author 道一源码
 */
@Service
@Validated
public class ArticleDetailServiceImpl implements ArticleDetailService {

    @Resource
    private ArticleDetailMapper articleDetailMapper;
    @Resource
    private TagDictionaryMapper tagDictionaryMapper;

    @Override
    public Long createArticleDetail(ArticleDetailSaveReqVO createReqVO) {
        // 插入
        ArticleDetailDO articleDetail = BeanUtils.toBean(createReqVO, ArticleDetailDO.class);
        generatorSort(articleDetail);
        articleDetailMapper.insert(articleDetail);
        if (CollUtil.isNotEmpty(createReqVO.getTags())) {
            createReqVO.getTags().stream().distinct().forEach(tag -> {
                if (!tagDictionaryMapper.exists(new LambdaQueryWrapperX<TagDictionaryDO>().eq(TagDictionaryDO::getName, tag))) {
                    tagDictionaryMapper.insert(new TagDictionaryDO().setName(tag).setArticleCount(1L));
                } else {
                    tagDictionaryMapper.updateArticleCount(tag);
                }
            });
        }
        // 返回
        return articleDetail.getId();
    }

    @Override
    public void updateArticleDetail(ArticleDetailSaveReqVO updateReqVO) {
        // 校验存在
        validateArticleDetailExists(updateReqVO.getId());
        // 更新
        ArticleDetailDO updateObj = BeanUtils.toBean(updateReqVO, ArticleDetailDO.class);
        generatorSort(updateObj);
        articleDetailMapper.updateById(updateObj);
        if (CollUtil.isNotEmpty(updateObj.getTags())) {
            updateObj.getTags().stream().distinct().forEach(tag -> {
                if (!tagDictionaryMapper.exists(new LambdaQueryWrapperX<TagDictionaryDO>().eq(TagDictionaryDO::getName, tag))) {
                    tagDictionaryMapper.insert(new TagDictionaryDO().setName(tag).setArticleCount(1L));
                } else {
                    tagDictionaryMapper.updateArticleCount(tag);
                }
            });
        }
    }

    private void generatorSort(ArticleDetailDO bean) {
        if (CollUtil.contains(bean.getTags(), "置顶")) {
            if (bean.getSort() > 0) {
                bean.setSort(bean.getSort() * -1);
            }
        } else {
            if (bean.getSort() < 0) {
                bean.setSort(bean.getSort() * -1);
            }
        }
    }

    @Override
    public void deleteArticleDetail(Long id) {
        // 校验存在
        validateArticleDetailExists(id);
        // 删除
        articleDetailMapper.deleteById(id);
    }

    private void validateArticleDetailExists(Long id) {
        if (articleDetailMapper.selectById(id) == null) {
            throw exception(ARTICLE_DETAIL_NOT_EXISTS);
        }
    }

    @Override
    public ArticleDetailDO getArticleDetail(Long id) {
        return articleDetailMapper.selectById(id);
    }

    @Override
    public ArticleDetailDO getArticleDetail(Long id, boolean isRead) {
        if (isRead) {
            articleDetailMapper.updateReadCount(id);
        }
        return getArticleDetail(id);
    }

    @Override
    public PageResult<ArticleDetailDO> getArticleDetailPage(ArticleDetailPageReqVO pageReqVO) {
        return articleDetailMapper.selectPage(pageReqVO);
    }

}
